from app import db
from app.models import Certificate
from PIL import Image, ImageDraw, ImageFont
import os
from datetime import datetime
from loguru import logger

class CertificateService:
    """证书服务类"""
    
    def __init__(self):
        self.upload_folder = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'uploads', 'certificates')
        os.makedirs(self.upload_folder, exist_ok=True)
    
    def generate_certificate(self, exam_record):
        """生成证书"""
        try:
            # 检查是否已有证书
            existing_certificate = Certificate.query.filter_by(
                exam_record_id=exam_record.id
            ).first()
            
            if existing_certificate:
                return existing_certificate
            
            # 创建证书
            certificate = Certificate.create_certificate(
                user_id=exam_record.user_id,
                exam_record_id=exam_record.id,
                score=exam_record.score
            )
            
            # 生成证书图片
            image_url = self.generate_certificate_image(certificate)
            certificate.certificate_url = image_url
            db.session.commit()
            
            logger.info(f"证书生成成功: {certificate.certificate_no}")
            return certificate
            
        except Exception as e:
            logger.error(f"生成证书失败: {e}")
            raise
    
    def generate_certificate_image(self, certificate):
        """生成证书图片"""
        try:
            # 创建证书图片
            width, height = 800, 600
            image = Image.new('RGB', (width, height), color='white')
            draw = ImageDraw.Draw(image)
            
            # 尝试加载字体，如果失败则使用默认字体
            try:
                title_font = ImageFont.truetype('arial.ttf', 36)
                subtitle_font = ImageFont.truetype('arial.ttf', 24)
                content_font = ImageFont.truetype('arial.ttf', 18)
            except:
                title_font = ImageFont.load_default()
                subtitle_font = ImageFont.load_default()
                content_font = ImageFont.load_default()
            
            # 绘制边框
            draw.rectangle([(20, 20), (width-20, height-20)], outline='gold', width=3)
            
            # 绘制标题
            title = "好爸爸证书"
            title_bbox = draw.textbbox((0, 0), title, font=title_font)
            title_width = title_bbox[2] - title_bbox[0]
            title_x = (width - title_width) // 2
            draw.text((title_x, 80), title, fill='darkblue', font=title_font)
            
            # 绘制副标题
            subtitle = "恭喜您通过月子护理知识考试！"
            subtitle_bbox = draw.textbbox((0, 0), subtitle, font=subtitle_font)
            subtitle_width = subtitle_bbox[2] - subtitle_bbox[0]
            subtitle_x = (width - subtitle_width) // 2
            draw.text((subtitle_x, 140), subtitle, fill='darkgreen', font=subtitle_font)
            
            # 绘制证书信息
            y_position = 220
            line_height = 30
            
            # 证书编号
            cert_no_text = f"证书编号: {certificate.certificate_no}"
            draw.text((100, y_position), cert_no_text, fill='black', font=content_font)
            y_position += line_height
            
            # 获得者姓名
            user_name = certificate.user.nickname or "用户"
            name_text = f"获得者: {user_name}"
            draw.text((100, y_position), name_text, fill='black', font=content_font)
            y_position += line_height
            
            # 考试得分
            score_text = f"考试得分: {certificate.score}分"
            draw.text((100, y_position), score_text, fill='black', font=content_font)
            y_position += line_height
            
            # 颁发日期
            issue_date = certificate.issue_date.strftime('%Y年%m月%d日')
            date_text = f"颁发日期: {issue_date}"
            draw.text((100, y_position), date_text, fill='black', font=content_font)
            y_position += line_height
            
            # 考试名称
            exam_name = certificate.exam_record.exam.title
            exam_text = f"考试名称: {exam_name}"
            draw.text((100, y_position), exam_text, fill='black', font=content_font)
            
            # 绘制底部说明
            bottom_text = "此证书证明您已掌握月子护理相关知识，是一位合格的好爸爸！"
            bottom_bbox = draw.textbbox((0, 0), bottom_text, font=content_font)
            bottom_width = bottom_bbox[2] - bottom_bbox[0]
            bottom_x = (width - bottom_width) // 2
            draw.text((bottom_x, height - 100), bottom_text, fill='gray', font=content_font)
            
            # 保存图片
            filename = f"certificate_{certificate.certificate_no}.png"
            filepath = os.path.join(self.upload_folder, filename)
            image.save(filepath, 'PNG')
            
            # 返回相对URL
            return f"/uploads/certificates/{filename}"
            
        except Exception as e:
            logger.error(f"生成证书图片失败: {e}")
            raise
    
    def get_certificate_image_path(self, certificate):
        """获取证书图片路径"""
        if not certificate.certificate_url:
            return None
        
        # 从URL中提取文件路径
        filename = certificate.certificate_url.split('/')[-1]
        return os.path.join(self.upload_folder, filename)
    
    def delete_certificate_image(self, certificate):
        """删除证书图片"""
        try:
            image_path = self.get_certificate_image_path(certificate)
            if image_path and os.path.exists(image_path):
                os.remove(image_path)
                logger.info(f"删除证书图片: {image_path}")
        except Exception as e:
            logger.error(f"删除证书图片失败: {e}") 